开发一个简单 vue 插件

以下是开发一个最简单的 vue 插件的基本文件配置及其内容:

文件目录:

文件目录

插件基本信息 package.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"name": "vue-toast-demo",
"version": "1.0.0",
"description": "a toast plugin for mobile",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"toast",
"vue-toast"
],
"author": "liu",
"license": "ISC",
"dependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"css-loader": "^1.0.0",
"node-sass": "^4.9.2",
"sass-loader": "^7.0.3",
"style-loader": "^0.21.0",
"vue": "^2.5.16",
"vue-loader": "^15.2.4",
"vue-style-loader": "^4.1.0",
"vue-template-compiler": "^2.5.16",
"webpack": "^3.1.0"
}
}

package.json 文件中,主要是对 vue,webpack,以及的对 vue 文件、js 和 css 打包需要的各种 loader 依赖。

vue 模板文件 vue-toast.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<template>
<section class="toast-containter">
<div class="toast" :class="[visible?'fade-in':'fade-out']">
<span>{{message}}</span>
</div>
</section>
</template>

<style lang="scss" scoped>
@keyframe fade-in{
0% {
opacity: 0;
transform: scale(0.7);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframe fade-out{
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.7);
}
}
.toast-containter {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 2000;
display: flex;
justify-content: center;
align-items: center;
.toast {
width: 180px;
height: 60px;
line-height: 60px;
text-align: center;
background-color: rgba(0,0,0,0.60);
border-radius: 10px;
color: #fff;
}
.fade-in{
animation-name: fade-in;
animation-duration: 0.3s;
animation-fill-mode: both;
-webkit-animation-fill-mode: both;
}
.fade-out{
animation-name: fade-out;
animation-duration: 0.3s;
animation-fill-mode: both;
-webkit-animation-fill-mode: both;
}
}
</style>

<script>
export default{
data(){
return{
message:'',
visible: false
}
}
}
</script>

该 vue 插件的模板文件,跟一个 vue 组件是完全一样的。

插件主要逻辑和入口 index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import ToastComponent from './vue-toast.vue'

let Toast = {}

//vue插件必须要有一个 install 方法 和 export default 该模块
Toast.install = function (Vue,options) {

var opt = {
duration: 3000
}

for(var key in options){
opt[key] = options[key]
}

Vue.prototype.$toast = function (message,option) { //在 Vue 的原型链上拓展 $toast 方法

if(typeof option == 'object'){
for(var key in option){
opt[key] = option[key]
}
}

const ToastController = Vue.extend(ToastComponent)

var instance = new ToastController().$mount(document.createElement("div"))

instance.message = message
instance.visible = true

document.body.appendChild(instance.$el)

setTimeout(()=>{
instance.visible = false
document.body.removeChild(instance.$el)
},opt.duration)
}

Vue.prototype.$toast['show'] = function(message,option){ //拓展方法$toast.show
Vue.prototype.$toast(message,option);
}

Vue.prototype.$toast['success'] = function(message,option){ //拓展方法$toast.success
Vue.prototype.$toast(message,option);
}
}

if(window.Vue){ //如果是全局引用,则 use 插件
Vue.use(Toast);
}

export default Toast;

在 index.js 文件中实现插件的逻辑和功能,也是 webpack 的入口文件。

webpack 打包配置文件 webpack.config.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
var path = require('path');
//使用前需要先引入VueLoaderPlugin
var { VueLoaderPlugin } = require('vue-loader');

module.exports = {
entry: './src/lib/index.js',
output: {
path: path.join(__dirname,'./dist'),//用path.join来把相对路径改为绝对路径
filename: 'vue-toast-demo.js',
libraryTarget: 'umd', //指定打包出来的文件格式 例如amd,cmd,requirejs,commomjs,es6,umd,其中umd为兼容规范(推荐)
library: 'VueToastDemo' //文件引用名称
},
module:{
rules:[
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
},
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
],
},
{
test:/\.vue$/,
loader: 'vue-loader',
//webpack打包的时候排除node_modules目录
exclude: /node_modules/,
options: { //vue文件内部解析
loaders: {
//webpack解析从右到左
//"scss": 'style-loader!css-loader!sass-loader',
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
}
},
{
test:/\.js$/,
loader: 'babel-loader',
//指定js后缀的文件需要打包的文件路径
include: path.join(__dirname,'src'),
exclude: /node_modules/
}
]
},
plugins:[
//Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的
new VueLoaderPlugin()
]
}

es6 babel 配置文件 .babelrc:

1
2
3
{
"presets": ["env"]
}

插件测试页面:index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script type="text/javascript" src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript" src="../dist/vue-toast-demo.js"></script>
</head>
<body>
<div id="app">
<a href="javascript:;" @click="toast">点击弹出Toast</a>
</div>

<script type="text/javascript">
new Vue({
el: '#app',
methods:{
toast:function(){
this.$toast.show("你好,Toast!");
}
}
})
</script>
</body>
</html>

发布插件:

  1. 注册 npm 账号
  2. npm adduser
  3. npm publish

需要注意一点的是,发布的插件不能与已发布的插件重名,最好写一个 README.md 来介绍你发布插件的介绍和使用。



完~